/// @tags: EulerCiruit
#include <cctype>
#include <cstdio>
#include <vector>

int const N = 1e5 + 5, M = 3e5 + 5;

template <typename T>
inline T &read(T &x) {
  x = 0;
  bool f = false;
  short ch = getchar();
  while (!isdigit(ch)) {
    if (ch == '-') f = true;
    ch = getchar();
  }
  while (isdigit(ch)) x = x * 10 + (ch ^ '0'), ch = getchar();
  if (f) x = -x;
  return x;
}

int n, rt1, e_cnt, rt2;
int deg1[N], deg2[N], A[N], B[N], ans[N];
int eu[M], ev[M], dir[M];
std::vector<int> G[N * 2];

inline void add(int u, int v) {
  ++e_cnt, eu[e_cnt] = u, ev[e_cnt] = v;
  G[u].emplace_back(e_cnt);
  G[v].emplace_back(e_cnt);
}

void dfs(int u) {
  while (!G[u].empty()) {
    int e = G[u].back();
    G[u].pop_back();
    if (!dir[e]) {
      dir[e] = u == eu[e] ? 1 : 2;
      dfs(eu[e] ^ ev[e] ^ u);
    }
  }
}

int main() {
#ifndef ONLINE_JUDGE
#ifdef LOCAL
  freopen("/tmp/CodeTmp/testdata.in", "r", stdin);
  freopen("/tmp/CodeTmp/testdata.out", "w", stdout);
#else
  freopen("AT2675 [AGC018F] Two Trees.in", "r", stdin);
  freopen("AT2675 [AGC018F] Two Trees.out", "w", stdout);
#endif
#endif

  read(n);
  for (int i = 1; i <= n; ++i) read(A[i]);
  for (int i = 1; i <= n; ++i) read(B[i]);
  for (int i = 1; i <= n; ++i) {
    if (A[i] != -1) {
      ++deg1[A[i]], ++deg1[i];
      add(A[i], i);
    } else
      rt1 = i;
    if (B[i] != -1) {
      ++deg2[B[i]], ++deg2[i];
      add(n + B[i], n + i);
    } else
      rt2 = i;
  }
  ++deg1[rt1], ++deg2[rt2];
  add(0, rt1), add(0, n + rt2);
  for (int i = 1; i <= n; ++i)
    if ((deg1[i] ^ deg2[i]) & 1) return puts("IMPOSSIBLE"), 0;
  puts("POSSIBLE");
  for (int i = 1; i <= n; ++i)
    if (deg1[i] & 1) add(i, n + i);
  dfs(0);
  for (int i = n * 2 + 1; i <= e_cnt; ++i) ans[eu[i]] = dir[i] == 1 ? 1 : -1;
  for (int i = 1; i <= n; ++i) printf("%d ", ans[i]);
  return 0;
}